#include <stdio.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
#include <string>
#include <string.h>

struct Rectangle {
    int x = 0;
    int y = 0;
    int    width  = 0;
    int    height = 0;
};

struct ScreenInfo{
    Rectangle geometry;
    unsigned short rotation;
};

ScreenInfo getScreenInfo(const std::string &screen_name)  {
    ScreenInfo screen_info;
    // 初始化Screen的信息
    screen_info.rotation = RR_Rotate_0;
    screen_info.geometry.x = 0;
    screen_info.geometry.y = 0;
    screen_info.geometry.width = 0;
    screen_info.geometry.height = 0;
    Display *display = XOpenDisplay(":0");
    Window root = XDefaultRootWindow(display);
    static Window last_root;
    static XRRScreenResources *res = nullptr;
    last_root = XDefaultRootWindow(display);
    if(!res || last_root != root)
    {
        last_root = root;
        res = XRRGetScreenResources(display, root);
    }
    if(!res)
    {
//        std::cout << "Error: could not get screen resources!" << std::endl;
        printf("Error: could not get screen resources!");
        return screen_info;
    }
    bool isfind = false;
    for(int i = 0;i < res->ncrtc;++i)
    {
        XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(display, res, res->crtcs[i]);
        if (crtc_info)
        {
            for(int o = 0;o < crtc_info->noutput; ++o)
            {
                XRROutputInfo *output_info = XRRGetOutputInfo(display, res, crtc_info->outputs[o]);
                if (!output_info) {
                    printf("Error: can not get out put info");
                    continue;
                }
                if(!strcmp(output_info->name, screen_name.c_str()))
                {
                    isfind = true;
                    screen_info.rotation = crtc_info->rotation;
                    screen_info.geometry.x = crtc_info->x;
                    screen_info.geometry.y = crtc_info->y,
                    screen_info.geometry.width = crtc_info->width,
                    screen_info.geometry.height = crtc_info->height;
                    XRRFreeOutputInfo(output_info);
                    //break;
                }
                    
                printf("scr.name:%s, scr.con:%d\n", output_info->name, output_info->connection);
           }
            XRRFreeCrtcInfo(crtc_info);
        }
        else {
            printf("Error: can not get crtc info");
        }

        if(isfind) break;
    }

    if(!isfind)
    {
        printf("Error: could not get screen info!");
    }
    if (display != nullptr) {
        XCloseDisplay(display);
    }
    return screen_info;
}

Rectangle getDesktopResolution(void) { //整个桌面分辨率
    int       screen = -1;
    Rectangle resolution;
    Display * display = XOpenDisplay(":0");
    screen            = DefaultScreen(display);
    resolution.width  = DisplayWidth(display, screen);
    resolution.height = DisplayHeight(display, screen);

//    std::cout << "resolution.width = " << resolution.width;
//    std::cout << "; resolution.height = " << resolution.height << std::endl;


    if (display != nullptr) {
        XCloseDisplay(display);
    }
    return resolution;
}


int main() {
    Rectangle resolution = getDesktopResolution();
    printf("res.width:%d, res.height:%d\n", resolution.width, resolution.height);
    ScreenInfo sinf = getScreenInfo("HDMI-0");
    printf("sinf.x:%d, sinf.y:%d, sinf.width:%d, sinf.height:%d, sinf.rota:%d\n", sinf.geometry.x, sinf.geometry.y, sinf.geometry.width, sinf.geometry.height, sinf.rotation);
    return 0;
}

